#include <iostream>
#include <sw/redis++/redis++.h>
#include <vector>
#include <string>
#include "PPrint.hpp"
#include <chrono>

using std::cout;
using std::endl;
using std::string;
using std::unordered_map;
using std::vector;

using sw::redis::Redis;

void test1(Redis &redis)
{
    cout << "string -> set and get way: " << endl;
    redis.flushall();

    redis.set("key1", "111");
    auto value = redis.get("key1");
    if (value)
    {
        cout << "value: " << value.value() << endl;
    }

    redis.set("key1", "222");
    value = redis.get("key1");
    if (value)
    {
        cout << "value: " << value.value() << endl;
    }

    return;
}

void test2(Redis &redis)
{
    cout << "set --> time" << endl;
    redis.flushall();

    redis.set("key1", "111", std::chrono::seconds(5));

    std::this_thread::sleep_for(std::chrono::seconds(3));
    std::cout << "time: " << redis.ttl("key1") << endl;

    return;
}

void test3(Redis &redis)
{
    cout << "set NX and XX" << endl;
    redis.flushall();

    redis.set("key1", "111", 0, sw::redis::UpdateType::EXIST);
    auto value = redis.get("key1");
    if (value)
        cout << value.value() << endl;
    else
        cout << "key1 not exist" << endl;
}

void test4(Redis &redis)
{
    std::cout << "mset" << std::endl;
    redis.flushall();

    vector<sw::redis::OptionalString> v;
    auto it = std::back_inserter(v);
    redis.mset({std::make_pair("key1", "111"), std::make_pair("key2", "222"), std::make_pair("key3", "333")});
    redis.mget({"key1", "key2", "key3", "key4"}, it);
    printContainerOptional(v);
}

void test5(Redis &redis)
{
    std::cout << "getrange and setrange" << std::endl;
    redis.flushall();

    redis.set("key", "abcdefghijk");

    string result = redis.getrange("key", 2, 5);
    cout << "result: " << result << endl;

    redis.setrange("key", 2, "xyz");
    auto value = redis.get("key");
    cout << "value: " << value.value() << endl;
}

void test6(Redis &redis)
{
    cout << "incr and decr" << endl;
    redis.flushall();

    redis.set("key1", "100");
    auto result = redis.incr("key1");
    cout << result << endl;

    result = redis.decrby("key1", 2);
    cout << result << endl;
}

int main()
{
    Redis redis("tcp://127.0.0.1:6379");

    test6(redis);

    return 0;
}